<!-- 在script 标签上使用setup，可以不用再使用return的写法了 -->
<!-- 其中 setup 标记的 script 必须是单独的，不能和export等其他共用 -->
<!-- 可以使用  npm i vite-plugin-vue-setup-extend -D 插件替换下面的写法，直接将组件名称定义写到script的name属性上 -->
<!--<script lang="ts">
export default {
  name: 'Person',
}
</script>-->

<!-- 可以使用  npm i vite-plugin-vue-setup-extend -D 插件替换下面的写法，直接将组件名称定义写到script的name属性上 -->
<!-- 如果没有定义组件名称，没有给script写name定义组件名称的话，默认就是组件的名称。 -->
<script setup lang="ts" name="Person">
import { reactive, watch } from 'vue'

let person = reactive({
  name: '张三',
  age: 18,
  car: {
    name1: '奔驰',
    name2: '宝马',
  },
})

// 修改第一台车
function changeCar1() {
  person.car.name1 += '!'
}
// 修改第二台车
function changeCar2() {
  person.car.name2 += '!'
}
// 修改整台车
function changeCar() {
  person.car = {
    name1: '雅迪',
    name2: '雅马哈',
  }
}

/**
 * 监视ref或reactive定义的【对象类型】数据中的某个属性，注意点如下：
 *    - 若该属性值不是【对象类型】，需要写成函数形式。
 *    - 若该属性值是依然是【对象类型】，可直接编，也可写成函数，建议写成函数。
 *    - 结论：监视的要是对象里的属性，那么最好写函数式，注意点：若是对象监视的是地址值，需要关注对象内部，需要手动开启深度监视。
 */
// 监视，情况四：监视响应式对象中的某个属性，且该属性是基本类型的，要写成函数式
watch(
  () => {
    // 如果写成这样的写法的话，就只是监视person的name属性
    // console.log('person.name变化了！')
    return person.name
  },
  (newValue, oldValue) => {
    // 若修改整个ref定义的对象，newValue 是新值， oldValue 是旧值，因为不是同一个对象了。
    // 若修改的是ref定义的对象中的属性，newValue 和 oldValue 都是新值，因为它们是同一个对象。
    console.log('person.name变化了', newValue, oldValue)
  },
  {
    deep: true, // 深度监视
    immediate: true, // 立即监视
  },
)

// 监视，情况四：监视响应式对象中的某个属性，且该属性是对象类型的，可以直接写，也能写函数，更推荐写函数
watch(
  () => person.car,
  (newValue, oldValue) => {
    console.log('person.car变化了', newValue, oldValue)
  },
  { deep: true }, // 写成函数形式 + deep 深度监视的形式来解决监视对象类型里面的属性，以及整个对象的监视
)

// // 监视，情况四：监视响应式对象中的某个属性，且该属性是对象类型的，可以直接写，也能写函数，更推荐写函数
// // 这样的写法只能监视对象里面的属性，而不能监视整个对象
// watch(
//   person.car,
//   (newValue, oldValue) => {
//     console.log('person.car变化了', newValue, oldValue)
//   },
//   { deep: true },
// )
</script>

<template>
  <div class="person">
    <h1>情况四：监视【ref】或【reactive】定义的【对象类型】数据中的某个属性</h1>
    <h1>姓名：{{ person.name }}</h1>
    <h1>年龄：{{ person.age }}</h1>
    <h1>汽车：{{ person.car.name1 }} {{ person.car.name2 }}</h1>
    <button @click="person.name += '!'">姓名变幻</button>
    <button @click="person.age += 1">年龄变幻</button>
    <button @click="changeCar1">修改第一台车</button>
    <button @click="changeCar2">修改第二台车</button>
    <button @click="changeCar">修改第整台车</button>
  </div>
</template>

<style scoped>
.person {
  background-color: #dab649;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}

button {
  margin: 0 10px;
}
</style>
